home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / sdk / vfw11.win / vfwdk / puzzproc.c_ / puzzproc.bin
Encoding:
Text File  |  1993-11-19  |  13.1 KB  |  465 lines

  1. /****************************************************************************
  2.  *
  3.  *  PUZZPROC.C
  4.  *
  5.  *  Modification of standard AVI drawing handler.
  6.  *
  7.  ***************************************************************************/
  8. /**************************************************************************
  9.  *
  10.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  11.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  12.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  13.  *  PURPOSE.
  14.  *
  15.  *  Copyright (c) 1992, 1993  Microsoft Corporation.  All Rights Reserved.
  16.  * 
  17.  **************************************************************************/
  18.  
  19. #include <windows.h>
  20. #include <windowsx.h>
  21. #include <vfw.h>
  22. #include "puzzle.h"
  23.  
  24. #define SZCODE char _based(_segname("_CODE"))
  25. static SZCODE szDescription[] = "Microsoft Puzzle Draw handler";
  26. static SZCODE szName[]        = "MS Puzzle";
  27.  
  28. #define FOURCC_AVIDraw      mmioFOURCC('P','U','Z','Z')
  29. #define VERSION_AVIDraw     0x00010000      // 1.00
  30.  
  31. #ifndef HUGE
  32.     #define HUGE _huge
  33. #endif
  34.  
  35. extern PUZZLE    gPuzzle;
  36.  
  37. /***************************************************************************
  38.  ***************************************************************************/
  39.  
  40. typedef struct {
  41.     HDRAWDIB        hdd;
  42.  
  43.     HDC                 hdc;            // HDC to draw to
  44.                  
  45.     int                 xDst;           // destination rectangle
  46.     int                 yDst;
  47.     int                 dxDst;
  48.     int                 dyDst;
  49.     int                 xSrc;           // source rectangle
  50.     int                 ySrc;
  51.     int                 dxSrc;
  52.     int                 dySrc;
  53.     LPBYTE        lpBuffer;
  54. } INSTINFO, FAR * PINSTINFO;
  55.  
  56. // static stuff in this file.
  57. LONG FAR PASCAL _export ICAVIDrawProc(DWORD id, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2);
  58. static LONG NEAR PASCAL AVIDrawOpen(ICOPEN FAR * icopen);
  59. static LONG NEAR PASCAL AVIDrawClose(PINSTINFO pi);
  60. static LONG NEAR PASCAL AVIDrawGetInfo(ICINFO FAR *icinfo, LONG lSize);
  61. static LONG NEAR PASCAL AVIDrawQuery(PINSTINFO pi, LPBITMAPINFOHEADER lpbiIn);
  62. static LONG NEAR PASCAL AVIDrawSuggestFormat(PINSTINFO pi, ICDRAWSUGGEST FAR *lpicd, LONG cbicd);
  63. static LONG NEAR PASCAL AVIDrawBegin(PINSTINFO pi, ICDRAWBEGIN FAR *lpicd, LONG cbicd);
  64. static LONG NEAR PASCAL AVIDraw(PINSTINFO pi, ICDRAW FAR *lpicd, LONG cbicd);
  65. static LONG NEAR PASCAL AVIDrawEnd(PINSTINFO pi);
  66. static LONG NEAR PASCAL AVIDrawChangePalette(PINSTINFO pi, LPBITMAPINFOHEADER lpbi);
  67.  
  68. /***************************************************************************
  69.  ***************************************************************************/
  70.  
  71. LONG FAR PASCAL _export ICAVIDrawProc(DWORD id, HDRVR hDriver, UINT uiMessage, LPARAM lParam1, LPARAM lParam2)
  72. {
  73.     PINSTINFO pi = (PINSTINFO)id;
  74.  
  75.     switch (uiMessage)
  76.     {
  77.         case DRV_LOAD:
  78.         case DRV_FREE:
  79.             return 1;
  80.  
  81.         /*********************************************************************
  82.             open
  83.         *********************************************************************/
  84.  
  85.         case DRV_OPEN:
  86.             if (lParam2 == 0L)
  87.                 return 1;
  88.  
  89.             return AVIDrawOpen((ICOPEN FAR *)lParam2);
  90.  
  91.     case DRV_CLOSE:
  92.             return AVIDrawClose(pi);
  93.  
  94.         /*********************************************************************
  95.             Configure/Info messages
  96.         *********************************************************************/
  97.  
  98.         case DRV_QUERYCONFIGURE:    // configuration from drivers applet
  99.             return 0;
  100.  
  101.         case DRV_CONFIGURE:
  102.             return 1;
  103.  
  104.         case ICM_CONFIGURE:
  105.         case ICM_ABOUT:
  106.             return ICERR_UNSUPPORTED;
  107.  
  108.         /*********************************************************************
  109.             state messages
  110.         *********************************************************************/
  111.  
  112.         case ICM_GETSTATE:
  113.         case ICM_SETSTATE:
  114.             return 0L;
  115.  
  116.         case ICM_GETINFO:
  117.             return AVIDrawGetInfo((ICINFO FAR *)lParam1, lParam2);
  118.  
  119.         /*********************************************************************
  120.             draw messages
  121.         *********************************************************************/
  122.  
  123.         case ICM_DRAW_QUERY:
  124.             return AVIDrawQuery(pi, (LPBITMAPINFOHEADER)lParam1);
  125.  
  126.     case ICM_DRAW_SUGGESTFORMAT:
  127.         return AVIDrawSuggestFormat(pi, (ICDRAWSUGGEST FAR *) lParam1, lParam2);
  128.  
  129.         case ICM_DRAW_BEGIN:
  130.         return AVIDrawBegin(pi, (ICDRAWBEGIN FAR *) lParam1, lParam2);
  131.  
  132.     case ICM_DRAW_REALIZE:
  133.         pi->hdc = (HDC) lParam1;
  134.         
  135.         if (!pi->hdc || !pi->hdd)
  136.         break;
  137.  
  138.         return DrawDibRealize(pi->hdd, pi->hdc, (BOOL) lParam2);
  139.  
  140.     case ICM_DRAW_GET_PALETTE:
  141.         if (!pi->hdd)
  142.         break;
  143.  
  144.         return (LONG) (UINT) DrawDibGetPalette(pi->hdd);
  145.         
  146.         case ICM_DRAW:
  147.             return AVIDraw(pi, (ICDRAW FAR *)lParam1, lParam2);
  148.  
  149.     case ICM_DRAW_CHANGEPALETTE:
  150.         return AVIDrawChangePalette(pi, (LPBITMAPINFOHEADER) lParam1);
  151.                 
  152.         case ICM_DRAW_END:
  153.             return AVIDrawEnd(pi);
  154.  
  155.         /*********************************************************************
  156.             standard driver messages
  157.         *********************************************************************/
  158.  
  159.         case DRV_DISABLE:
  160.         case DRV_ENABLE:
  161.             return 1;
  162.  
  163.         case DRV_INSTALL:
  164.         case DRV_REMOVE:
  165.             return 1;
  166.     }
  167.  
  168.     if (uiMessage < DRV_USER)
  169.         return DefDriverProc(id,hDriver,uiMessage,lParam1,lParam2);
  170.     else
  171.         return ICERR_UNSUPPORTED;
  172. }
  173.  
  174. /*****************************************************************************
  175.  *
  176.  * AVIDrawOpen() is called from the DRV_OPEN message
  177.  *
  178.  ****************************************************************************/
  179.  
  180. static LONG NEAR PASCAL AVIDrawOpen(ICOPEN FAR * icopen)
  181. {
  182.     PINSTINFO pinst;
  183.  
  184.     //
  185.     // refuse to open if we are not being opened as a video draw device
  186.     //
  187.     if (icopen->fccType != streamtypeVIDEO)
  188.         return 0;
  189.     
  190.     if (icopen->dwFlags == ICMODE_COMPRESS)
  191.         return 0;
  192.  
  193.     if (icopen->dwFlags == ICMODE_DECOMPRESS)
  194.         return 0;
  195.  
  196.     pinst = (PINSTINFO)GlobalAllocPtr(GHND, sizeof(INSTINFO));
  197.  
  198.     if (!pinst)
  199.     {
  200.         icopen->dwError = ICERR_MEMORY;
  201.         return NULL;
  202.     }
  203.  
  204.     //
  205.     // init structure
  206.     //
  207.     pinst->hdd = DrawDibOpen();
  208.  
  209.     //
  210.     // return success.
  211.     //
  212.     icopen->dwError = ICERR_OK;
  213.  
  214.     return (LONG) pinst;
  215. }
  216.  
  217. /*****************************************************************************
  218.  *
  219.  * Close() is called on the DRV_CLOSE message.
  220.  *
  221.  ****************************************************************************/
  222. static LONG NEAR PASCAL AVIDrawClose(PINSTINFO pi)
  223. {
  224.     if (pi->hdd) {
  225.     DrawDibClose(pi->hdd);
  226.     }
  227.     
  228.     if (pi->lpBuffer) {
  229.     GlobalFreePtr(pi->lpBuffer);
  230.     }
  231.     
  232.     GlobalFreePtr(pi);
  233.     
  234.     return 1;
  235. }
  236.  
  237. /*****************************************************************************
  238.  *
  239.  * AVIDrawGetInfo() implements the ICM_GETINFO message
  240.  *
  241.  ****************************************************************************/
  242. static LONG NEAR PASCAL AVIDrawGetInfo(ICINFO FAR *icinfo, LONG lSize)
  243. {
  244.     if (icinfo == NULL)
  245.         return sizeof(ICINFO);
  246.  
  247.     if (lSize < sizeof(ICINFO))
  248.         return 0;
  249.  
  250.     icinfo->dwSize        = sizeof(ICINFO);
  251.     icinfo->fccType        = ICTYPE_VIDEO;
  252.     icinfo->fccHandler      = FOURCC_AVIDraw;
  253.     icinfo->dwFlags        = VIDCF_DRAW;
  254.     icinfo->dwVersion       = VERSION_AVIDraw;
  255.     icinfo->dwVersionICM    = ICVERSION;
  256.     lstrcpy(icinfo->szDescription, szDescription);
  257.     lstrcpy(icinfo->szName, szName);
  258.  
  259.     return sizeof(ICINFO);
  260. }
  261.  
  262. /*****************************************************************************
  263.  *
  264.  * AVIDrawQuery() implements ICM_DRAW_QUERY
  265.  *
  266.  ****************************************************************************/
  267. static LONG NEAR PASCAL AVIDrawQuery(PINSTINFO pi,
  268.              LPBITMAPINFOHEADER lpbiIn)
  269. {
  270.     //
  271.     // determine if the input DIB data is in a format we like.
  272.     //
  273.     if (lpbiIn == NULL)
  274.         return ICERR_BADFORMAT;
  275.  
  276.     //
  277.     // determine if the input DIB data is in a format we like.
  278.     //
  279.     if (lpbiIn->biCompression != BI_RGB)
  280.         return ICERR_BADFORMAT;
  281.  
  282.     return ICERR_OK;
  283. }
  284.  
  285. /*****************************************************************************
  286.  *
  287.  * AVIDrawSuggestFormat() implements ICM_DRAW_SUGGESTFORMAT
  288.  *
  289.  ****************************************************************************/
  290.  
  291. static LONG NEAR PASCAL AVIDrawSuggestFormat(PINSTINFO pi, ICDRAWSUGGEST FAR *lpicd, LONG cbicd)
  292. {
  293.     HIC hic;
  294.     
  295.     if (lpicd->lpbiSuggest == NULL)
  296.     return sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
  297.  
  298.     //
  299.     // Call COMPMAN to get a good format to display data in....
  300.     //
  301.     hic = ICGetDisplayFormat(NULL, lpicd->lpbiIn, lpicd->lpbiSuggest,
  302.                  0, lpicd->dxDst, lpicd->dyDst);
  303.  
  304.     if (hic)
  305.     ICClose(hic);
  306.  
  307.     if (lpicd->lpbiSuggest) {
  308.     if (lpicd->lpbiSuggest->biCompression == BI_RLE8)
  309.         lpicd->lpbiSuggest->biCompression = BI_RGB;
  310.     }
  311.     
  312.     // !!! Should check this format here to make sure it's RGB...
  313.  
  314.     // !!! If not, we could force it to 8-bit....
  315.  
  316.     return sizeof(BITMAPINFOHEADER) + lpicd->lpbiSuggest->biClrUsed * sizeof(RGBQUAD);
  317. }
  318.  
  319. /*****************************************************************************
  320.  *
  321.  * AVIDrawBegin() implements ICM_DRAW_BEGIN
  322.  *
  323.  ****************************************************************************/
  324.  
  325. static LONG NEAR PASCAL AVIDrawBegin(PINSTINFO pi, ICDRAWBEGIN FAR *lpicd, LONG cbicd)
  326. {
  327.     LONG    l;
  328.  
  329.     l = AVIDrawQuery(pi, lpicd->lpbi);
  330.  
  331.     if ((l != 0) || (lpicd->dwFlags & ICDRAW_QUERY))
  332.     return l;
  333.  
  334.     // Copy over whatever we want to remember
  335.     pi->hdc = lpicd->hdc;
  336.     pi->xDst = lpicd->xDst;
  337.     pi->yDst = lpicd->yDst;
  338.     pi->dxDst = lpicd->dxDst;
  339.     pi->dyDst = lpicd->dyDst;
  340.     pi->xSrc = lpicd->xSrc;
  341.     pi->ySrc = lpicd->ySrc;
  342.     pi->dxSrc = lpicd->dxSrc;
  343.     pi->dySrc = lpicd->dySrc;
  344.  
  345.     SetStretchBltMode(pi->hdc, COLORONCOLOR);
  346.  
  347.     if (!DrawDibBegin(pi->hdd, pi->hdc,
  348.          pi->dxDst, pi->dyDst,
  349.          lpicd->lpbi,
  350.          pi->dxSrc, pi->dySrc,
  351.          0)) {  // !!! Flags?
  352.     return ICERR_UNSUPPORTED;
  353.     }
  354.  
  355.     // !!! error check
  356.  
  357.  
  358.     //
  359.     // Allocate a buffer for the scrambled picture
  360.     //
  361.     if (pi->lpBuffer)
  362.     GlobalFreePtr(pi->lpBuffer);
  363.  
  364.     pi->lpBuffer = GlobalAllocPtr(GMEM_MOVEABLE, lpicd->lpbi->biSizeImage);
  365.  
  366.     if (!pi->lpBuffer)
  367.     return ICERR_MEMORY;
  368.         
  369.     return ICERR_OK;
  370. }
  371.  
  372.  
  373. /*****************************************************************************
  374.  *
  375.  * AVIDraw() implements ICM_DRAW
  376.  *
  377.  ****************************************************************************/
  378.  
  379. static LONG NEAR PASCAL AVIDraw(PINSTINFO pi, ICDRAW FAR *lpicd, LONG cbicd)
  380. {
  381.     UINT  wFlags;
  382.  
  383.     wFlags = DDF_SAME_HDC;
  384.  
  385.     if ((lpicd->dwFlags & ICDRAW_NULLFRAME) || lpicd->lpData == NULL) {
  386.     if (lpicd->dwFlags & ICDRAW_UPDATE)
  387.         wFlags |= DDF_UPDATE;
  388.     else
  389.         return ICERR_OK;        // nothing to draw
  390.     }
  391.  
  392.     if (lpicd->dwFlags & ICDRAW_PREROLL)
  393.     wFlags |= DDF_DONTDRAW;
  394.  
  395.     if (lpicd->dwFlags & ICDRAW_HURRYUP)
  396.     wFlags |= DDF_HURRYUP;
  397.  
  398.     //
  399.     // This is the only part that actually has to do with the puzzle:
  400.     // Mix up the picture into our extra buffer.
  401.     //
  402.     if (lpicd->lpData)
  403.     MixPicture(&gPuzzle, lpicd->lpFormat, lpicd->lpData, pi->lpBuffer);
  404.     
  405.     if (!DrawDibDraw(pi->hdd, pi->hdc,
  406.         pi->xDst, pi->yDst,
  407.         pi->dxDst, pi->dyDst,
  408.         lpicd->lpFormat,
  409.         pi->lpBuffer,
  410.         pi->xSrc, pi->ySrc,
  411.         pi->dxSrc, pi->dySrc,
  412.         wFlags)) {
  413.     if (wFlags & DDF_UPDATE)
  414.         return ICERR_CANTUPDATE;
  415.     else
  416.         return ICERR_UNSUPPORTED;
  417.     }
  418.     
  419.     return ICERR_OK;
  420. }
  421.  
  422.  
  423. /*****************************************************************************
  424.  *
  425.  * AVIDrawChangePalette() implements ICM_DRAW_CHANGE_PALETTE
  426.  *
  427.  ****************************************************************************/
  428.  
  429. static LONG NEAR PASCAL AVIDrawChangePalette(PINSTINFO pi, LPBITMAPINFOHEADER lpbi)
  430. {
  431.     PALETTEENTRY    ape[256];
  432.     LPRGBQUAD        lprgb;
  433.     int i;
  434.  
  435.     lprgb = (LPRGBQUAD) ((LPBYTE) lpbi + lpbi->biSize);
  436.     
  437.     for (i = 0; i < (int) lpbi->biClrUsed; i++) {
  438.     ape[i].peRed = lprgb[i].rgbRed;
  439.     ape[i].peGreen = lprgb[i].rgbGreen;
  440.     ape[i].peBlue = lprgb[i].rgbBlue;
  441.     ape[i].peFlags = 0;
  442.     }
  443.     
  444.     DrawDibChangePalette(pi->hdd, 0, (int) lpbi->biClrUsed,
  445.                  (LPPALETTEENTRY)ape);
  446.  
  447.     return ICERR_OK;
  448. }
  449.  
  450.  
  451. /*****************************************************************************
  452.  *
  453.  * AVIDrawEnd() implements ICM_DRAW_END
  454.  *
  455.  ****************************************************************************/
  456.  
  457. static LONG NEAR PASCAL AVIDrawEnd(PINSTINFO pi)
  458. {
  459.     // Note: do not call DrawDibEnd here, as we still may be asked to
  460.     // update our current display, and calling DrawDibEnd would wipe
  461.     // that out.
  462.     
  463.     return ICERR_OK;
  464. }
  465.